package global

import (
	"gindemo/common/settings"
	"gindemo/controller"
	"gindemo/filter"
	"io"
	"os"

	"github.com/gin-gonic/gin"
	"github.com/op/go-logging"
	"github.com/spf13/viper"
)

var format = logging.MustStringFormatter(
	`%{color}%{time:2006-01-02T15:04:05Z07:00} %{level:.5s} %{module:.10s}%{color:reset} %{message}`,
)

type GinService struct {
	Conf   *settings.AppConfig
	Logger *logging.Logger
	Engine *gin.Engine
	errs   chan error
}

func NewGinService() *GinService {
	return &GinService{
		errs: make(chan error),
	}
}

func (g *GinService) Run() {
	g.Logger.Info("开始启动服务...")
	// 根据配置文件启动gin服务
	// gin.SetMode(g.Conf.RunMode)
	Engine := gin.New()
	Engine.Use(gin.LoggerWithWriter(g.ginLoggerWriter(false, "wilog")))
	// Engine.Use(gin.RecoveryWithWriter(g.ginLoggerWriter(true, "welog")))
	Engine.Use(filter.ErrorWrapper)
	rootController := &controller.RootController{
		Logger: logging.MustGetLogger("ctrl"),
	}
	// 添加路由
	rootController.RouteAdd(Engine)
	// 加载模板
	// Engine.LoadHTMLGlob(g.Conf.StaticPath)
	// if len(g.Conf.TemplatePaths) > 0 {
	// 	for i := range g.Conf.TemplatePaths {
	// 		Engine.LoadHTMLGlob(g.Conf.TemplatePaths[i])
	// 	}
	// }
	// 静态文件
	Engine.Static("/", g.Conf.StaticPath)
	Engine.Run(g.Conf.Addr)
}

func (g *GinService) SetUpSetting(configPath string) error {
	// 初始化日志框架
	backend := logging.NewLogBackend(os.Stderr, "", 0)
	backendFormatter := logging.NewBackendFormatter(backend, format)
	logging.SetBackend(backendFormatter)
	g.Logger = logging.MustGetLogger("gin")
	g.Logger.Info("日志框架初始化成功！")
	// 初始化配置文件
	viper.SetConfigType("yaml")
	viper.SetConfigFile(configPath)
	g.Logger.Infof("开始读取配置文件，文件路径：%s", configPath)
	err := viper.ReadInConfig()
	if err != nil {
		return err
	}
	err = viper.Unmarshal(&g.Conf)
	if err != nil {
		return err
	}
	g.Logger.Infof("配置文件读取成功，配置内容：%v", g.Conf)
	return nil
}
func (g *GinService) ginLoggerWriter(isError bool, logName string) io.Writer {
	return &loggerWriter{IsError: isError, Logger: logging.MustGetLogger(logName)}
}

type loggerWriter struct {
	IsError bool
	Logger  *logging.Logger
}

func (lw *loggerWriter) Write(p []byte) (n int, err error) {
	if lw.IsError {
		lw.Logger.Error(string(p))
	} else {
		lw.Logger.Infof(string(p))
	}
	return len(p), nil
}
